import axios from 'axios';
import router from '@/router';
import Vue from 'vue';

const service = axios.create({
  withCredentials: true,
  baseURL: '/api',  
  timeout: 30000,
  // 下面这一行让 Axios 觉得 0~499 以内的状态都算"合法"，
  // 即便它是 401，也不会触发"XHR failed"这类浏览器级红色提示
  validateStatus(status) {
    return status < 500; // 只把 500 及以上当成真正的"网络错误"
  },
  // 自定义JSON解析，处理大整数精度丢失问题
  transformResponse: [function (data) {
    if (typeof data === 'string') {
      try {
        // 在JSON.parse之前，将长度超过15位的数字用引号包围，使其被解析为字符串
        const fixedData = data.replace(/:\s*(\d{15,})/g, ':"$1"');
        return JSON.parse(fixedData);
      } catch (e) {
        return data;
      }
    }
    return data;
  }]
});

// 防抖：避免多请求同时触发 401 时重复跳转
let isRedirectingToLogin = false;

service.interceptors.request.use(
  config => config,
  error => {
    // 不再打印任何请求级 error
    return Promise.reject(error);
  }
);

service.interceptors.response.use(
  response => {
    // ✅ 所有 2xx 状态码都会进入这里
    if (response.status === 200) {
      return response.data;
    }

    // ✅ 非 200 但 < 500 的状态码，比如 401, 403, 404 等
    const { status } = response;

    // 对于 4xx 状态码，不显示错误提示，但需要抛出错误以便进入 catch 块
    if (status === 401) {
      // 自动跳转登录页（带上重定向回来的地址）
      const currentPath = router.currentRoute && router.currentRoute.fullPath || '/';
      if (!isRedirectingToLogin && currentPath !== '/login') {
        isRedirectingToLogin = true;
        Vue.prototype.$message.error('登录已失效，请重新登录');
        router.replace({ path: '/login', query: { redirect: currentPath } }).finally(() => {
          setTimeout(() => { isRedirectingToLogin = false; }, 500);
        });
      }
      // 同时向调用方抛出 401 错误
      return Promise.reject({
        isAuthError: true,
        status: 401,
        message: '登录已失效，请重新登录',
        response: { status: status, data: '重新输入账号密码' }
      });
    }
    
    // 抛出错误，保留原始响应数据，让调用方能够捕获到
    return Promise.reject({
      response: {
        status: status,
        data: response.data
      }
    });
  },
  error => {
    // ❌ 只有网络错误、服务器错误（>=500）或 Axios 抛出的错误才会进入这里
    if (error.response) {
      const { status } = error.response;

      // 移除500错误的提示，静默处理
      if (status >= 500) {
        // 500及以上错误不显示提示，静默处理
        console.warn(`服务器错误 ${status}:`, error.response.data);
        return Promise.reject({
          response: {
            status: status,
            data: error.response.data
          }
        });
      }
      
      // 对于其他错误，抛出错误，保留原始响应数据
      return Promise.reject({
        response: {
          status: status,
          data: error.response.data
        }
      });
    } else if (error.message.includes('timeout')) {
      Vue.prototype.$message.error('请求超时，请检查网络');
      return Promise.reject(error);
    } else {
      Vue.prototype.$message.error('网络错误或服务不可达');
      return Promise.reject(error);
    }
  }
);

const request = {
  get(url, params = {}, config = {}) {
    return service.get(url, { params, ...config });
  },
  post(url, data = {}, config = {}) {
    return service.post(url, data, config);
  },
  delete(url, params = {}, config = {}) {
    return service.delete(url, { params, ...config });
  }
};

export default request;
